package tp.pr5.instructions;


import tp.pr5.Constants;
import tp.pr5.NavigationModule;
import tp.pr5.RobotEngine;
import tp.pr5.instructions.exceptions.InstructionExecutionException;
import tp.pr5.instructions.exceptions.WrongInstructionFormatException;
import tp.pr5.items.Item;
import tp.pr5.items.ItemContainer;

/**
 * The execution of this instruction shows the information of the inventory of the robot or the complete description about the item
 *  with identifier id contained in the inventory This Instruction works if the player writes SCAN or ESCANEAR (id is not mandatory)
 *
 */
public class ScanInstruction implements Instruction
{
	private ItemContainer robotContainer;
	private String id;
	
	/**
	 * Default constructor
	 */
	public ScanInstruction()
	{
		this.robotContainer = null;
		this.id = null;
	}
	
	/**
	 * Constructor with id
	 * 
	 * @param id of the item
	 */
	private ScanInstruction(String id)
	{
		this();
		this.id = id;
	}

	/**
	 * Parses the String returning an instance of RadarInstruction or throwing a WrongInstructionFormatException()
	 * 
	 * @param cad string given
	 */
	@Override
	public Instruction parse(String cad) throws WrongInstructionFormatException 
	{
		String[] entry = cad.toUpperCase().trim().split(" +");
		
		if((entry[0].equals("SCAN") || entry[0].equals("ESCANEAR")) && entry.length == 1)
		{
			return new ScanInstruction();
		}
		if((entry[0].equals("SCAN") || entry[0].equals("ESCANEAR")) && entry.length == 2)
		{
			return new ScanInstruction(entry[1]);
		}
		throw new WrongInstructionFormatException();
	}

	/**
	 * Fixes the current context, i.e., the robot engine and the navigation module
	 * 
	 * @param engine RobotEngine
	 * @param navigation NavigationModule
	 * @param robotContainer ItemContainer
	 * 
	 */
	@Override
	public void configureContext(RobotEngine engine, NavigationModule navigation, ItemContainer robotContainer) 
	{
		this.robotContainer = robotContainer;
	}

	/**
	 * Prints the description of a concrete item or the complete inventory of the robot
	 */
	@Override
	public void execute() throws InstructionExecutionException
	{
		
		try
		{	
			if(this.id == null)
			{
				if(this.robotContainer.numberOfItems() > 0)
				{
					this.robotContainer.requestScanCollection();
				}
				else
				{
					throw new InstructionExecutionException(Constants.MESSAGE_NO_ITEMS);
				}	
			}
			else
			{
				Item identifier = this.robotContainer.getItem(this.id);
				
				if(identifier != null)
				{
					this.robotContainer.requestScanItem(this.id);	
				} 
				else 
				{
					throw new InstructionExecutionException(Constants.MESSAGE_NO_ITEM.replace("{ID}", this.id));
				}
			}

		} catch(Exception e){
			throw e;
		}
	}

	/**
	 * Returns a description of the Instruction syntax. The string does not end with the line separator.
	 *  It is up to the caller adding it before printing.
	 */
	@Override
	public String getHelp() 
	{
		return "SCAN|ESCANEAR <id>";
	}

}
